﻿using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;

namespace Dot5Demo.Controls
{
    /// <summary>
    /// 本地工具方法
    /// </summary>
    public static class LocalToolUtil
    {
        /// <summary>
        /// 解析Windows消息的LParam，从低位获取x，从高位获取y，
        /// 组成一个Point返回。
        /// </summary>
        /// <param name="lParam"></param>
        /// <returns></returns>
        public static Point GetPoint(int lParam)
        {
            var x = LOWORD(lParam);
            var y = HIWORD(lParam);
            return new Point(x, y);
        }

        /// <summary>
        /// 解析Windows消息的LParam，从低位获取x，从高位获取y，
        /// 组成一个Point返回。
        /// </summary>
        /// <param name="lParam"></param>
        /// <returns></returns>
        public static Point GetPoint(IntPtr lParam)
        {
            var x = LOWORD(lParam);
            var y = HIWORD(lParam);
            return new Point(x, y);
        }

        public static int MAKELONG(int low, int high)
        {
            return (high << 16) | (low & 0xffff);
        }

        public static IntPtr MAKELPARAM(int low, int high)
        {
            return (IntPtr)((high << 16) | (low & 0xffff));
        }

        public static int HIWORD(int n)
        {
            return (n >> 16) & 0xffff;
        }

        public static int HIWORD(IntPtr n)
        {
            return HIWORD(unchecked((int)(long)n));
        }

        public static int LOWORD(int n)
        {
            return n & 0xffff;
        }

        public static int LOWORD(IntPtr n)
        {
            return LOWORD(unchecked((int)(long)n));
        }

        public static int SignedHIWORD(IntPtr n)
        {
            return SignedHIWORD(unchecked((int)(long)n));
        }

        public static int SignedLOWORD(IntPtr n)
        {
            return SignedLOWORD(unchecked((int)(long)n));
        }

        public static int SignedHIWORD(int n)
        {
            int i = (int)(short)((n >> 16) & 0xffff);

            return i;
        }

        public static int SignedLOWORD(int n)
        {
            int i = (int)(short)(n & 0xFFFF);

            return i;
        }

        /// <summary>
        /// 计算应传递给典型Win32调用的字符串大小。
        /// 在NT下是字符计数，在Windows 95下是ubyte计数。
        /// </summary>
        public static int GetPInvokeStringLength(String s)
        {
            if (s == null)
            {
                return 0;
            }

            if (Marshal.SystemDefaultCharSize == 2)
            {
                return s.Length;
            }
            else
            {
                if (s.Length == 0)
                {
                    return 0;
                }
                if (s.IndexOf('\0') > -1)
                {
                    return GetEmbeddedNullStringLengthAnsi(s);
                }
                else
                {
                    return lstrlen(s);
                }
            }
        }

        private static int GetEmbeddedNullStringLengthAnsi(String s)
        {
            int n = s.IndexOf('\0');
            if (n > -1)
            {
                String left = s.Substring(0, n);
                String right = s.Substring(n + 1);
                return GetPInvokeStringLength(left) + GetEmbeddedNullStringLengthAnsi(right) + 1;
            }
            else
            {
                return GetPInvokeStringLength(s);
            }
        }

        [DllImport(Win32Dlls.Kernel32, CharSet = CharSet.Auto)]
        [ResourceExposure(ResourceScope.None)]
        private static extern int lstrlen(String s);
    }

}